package jvs.vfs.ftp;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;

import jvs.vfs.IFileBaseImpl;

public class FtpFileImpl extends IFileBaseImpl {
		
	public FtpFileImpl(URI uri) {
		super(uri);
	}

	public boolean create() {
		try {
			Ftp ftp = get();
			if (exists()) {
				return false;
			}
			return ftp.put(new ByteArrayInputStream("".getBytes()), uri
					.getPath());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public boolean delete() {
		try {
			Ftp ftp = get();
			if (isDirectory()) {
				return ftp.rmdir(uri.getPath());
			} else {
				return ftp.delete(uri.getPath());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return false;
	}

	public boolean exists() {
		Ftp ftp;
		try {
			ftp = get();
			return ftp.exists(uri.getPath());
		} catch (IOException e) {
			e.printStackTrace();
		}

		return false;
	}

	public InputStream getInputStream() {
		Ftp ftp;
		InputStream is = null;
		try {
			ftp = get();
			is = ftp.getInputStream(uri.getPath());
		} catch (IOException e) {
			e.printStackTrace();
		}

		return is;
	}

	public long getLastModified() {
		Ftp ftp;
		try {
			ftp = get();
			return ftp.date(uri.getPath());
		} catch (IOException e) {
			e.printStackTrace();
		}

		return 0;
	}

	public long getLength() {
		Ftp ftp;
		try {
			ftp = get();
			return ftp.size(uri.getPath());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return -1;
	}

	public OutputStream getOutputStream() {
		Ftp ftp;
		OutputStream os = null;
		try {
			ftp = get();
			os = ftp.getOutputStream(uri.getPath());
		} catch (IOException e) {

			e.printStackTrace();
		}

		return os;
	}

	public boolean isDirectory() {
		Ftp ftp;
		try {
			ftp = get();
			return ftp.cd(uri.getPath());
		} catch (IOException e) {

			e.printStackTrace();
		}

		return false;
	}

	public boolean isFile() {
		return !isDirectory();
	}

	public String[] list() {
		Ftp ftp;
		String[] list = null;
		try {
			ftp = get();
			if (!isDirectory()) {
				return null;
			}
			list = ftp.ls(uri.getPath());

		} catch (IOException e) {
			e.printStackTrace();
		}
		return list;
	}

	public boolean mkdir() {
		Ftp ftp;
		try {
			ftp = get();
			return ftp.mkdir(uri.getPath());
		} catch (IOException e) {
			e.printStackTrace();
		}

		return false;
	}

	public boolean move(URI dest) {
		if (dest.getScheme().equalsIgnoreCase("ftp")) {
			Ftp ftp;
			try {
				ftp = get();
				return ftp.rename(uri.getPath(), dest.getPath());
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		return false;
	}

	/**/
	private static class FtpThreadLocal extends ThreadLocal<Ftp> {
		public Ftp initialValue() {
			return null;
		}
	}

	private static FtpThreadLocal ftl = new FtpThreadLocal();

	synchronized private Ftp get() throws IOException {
		//TODO rewrite and use pooling
		Ftp ftp = (Ftp) ftl.get();
		if (ftp == null) {
			String host = uri.getHost();
			int port = uri.getPort();
			if (port == -1) {
				port = 21;
			}
			String path = uri.getPath();
			int idx = uri.getUserInfo().indexOf(":");
			String user = uri.getUserInfo().substring(0, idx);
			String pass = uri.getUserInfo().substring(idx + 1);

			if (path == null || path.length() == 0) {
				path = "/";
			}
			ftp = new Ftp(host, port);
			ftp.login(user, pass);
			ftl.set(ftp);
		}
		return ftp;
	}
}
